package com.sojson.project.sys.user.controller;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.sojson.base.impl.BaseUser;
import com.sojson.config.exception.TransErrorCode;
import com.sojson.config.exception.bean.Status;
import com.sojson.constant.Constant;
import com.sojson.enums.EUserAuthStatus;
import com.sojson.enums.core.EUserCouponStatus;
import com.sojson.project.entity.vo.HotelOrderVo;
import com.sojson.project.entity.vo.OrderVo;
import com.sojson.project.entity.vo.PostApplyVo;
import com.sojson.project.entity.vo.UserCouponVo;
import com.sojson.project.service.HotelOrderService;
import com.sojson.project.service.OrderService;
import com.sojson.project.service.PostApplyService;
import com.sojson.project.service.UserCouponService;
import com.sojson.project.sys.user.controller.param.verify.UserParamVerify;
import com.sojson.project.sys.user.entity.bo.AuthcUser;
import com.sojson.project.sys.user.entity.dto.UserDto;
import com.sojson.project.sys.user.entity.dto.UserPageDto;
import com.sojson.project.sys.user.entity.po.User;
import com.sojson.project.sys.user.entity.vo.UserVo;
import com.sojson.project.sys.user.service.UserService;
import com.sojson.result.Result;
import com.sojson.util.ArithUtil;
import com.sojson.util.ExpUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.file.FileUtil;
import com.sojson.util.file.bean.UploadBean;
import com.sojson.util.idcard.IdCardUtil;
import com.sojson.util.pay.wx.WxUtil;
import com.sojson.util.token.TokenDto;
import com.sojson.util.token.TokenUtil;
import com.sojson.util.token.interfaces.BaseUserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 个人信息控制器
 *
 * @author liu
 * @date 2021-03-16
 */
@Api(tags = "个人信息管理")
@RestController
@RequestMapping(value = "/sys/user/user/profile")
public class UserProfileController extends BaseUserProfileController {

    @Autowired
    private UserService userService;
    @Autowired
    private PostApplyService postApplyService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private HotelOrderService hotelOrderService;
    @Autowired
    private UserCouponService userCouponService;

    /**
     * 修改个人信息
     *
     * @param dto
     * @return
     * @throws Exception
     */
    @PutMapping("/updateInfo")
    @PreAuthorize("@ss.login()")
    @ApiOperation("修改个人信息")
    public Result<Boolean> updateInfo(@RequestBody UserDto dto) throws Exception {
        dto.setId(TokenUtil.getUserId());
        // 校验参数
        Result<Boolean> paramResult = UserParamVerify.updateInfo(dto);
        // 验证不通过
        if (!paramResult.getCode().equals(TransErrorCode.SUCCESS.getCode())) {
            return paramResult;
        }

        return Result.success(userService.updateInfo(dto));
    }

    /**
     * 更新用户手机号
     *
     * @param dto
     * @return
     * @throws Exception
     */
    @PutMapping(value = "/updateMobile")
    @PreAuthorize("@ss.login()")
    @ApiOperation("更新用户手机号")
    public Result<Boolean> updateMobile(@RequestBody TokenDto dto) throws Exception {
        BaseUser user = dto.getUser();
        if (StringUtil.isNotBlankObject(user)) {
            user.setId(TokenUtil.getUserId());
        }
        // 校验参数
        Result<Boolean> paramResult = UserParamVerify.updateMobileById(dto);
        // 验证不通过
        if (!paramResult.getCode().equals(TransErrorCode.SUCCESS.getCode())) {
            return paramResult;
        }

        // 修改手机号
        userService.updateMobileById(dto);
        return Result.success();
    }

    /**
     * 通过id验证短信修改密码
     *
     * @param dto
     * @return
     * @throws Exception
     */
    @PutMapping(value = "/updatePwdBySms")
    @PreAuthorize("@ss.login()")
    @ApiOperation("通过id验证短信修改密码")
    public Result<Boolean> updatePwdBySms(@RequestBody TokenDto dto) throws Exception {
        // 校验参数
        Result<Boolean> paramResult = UserParamVerify.updatePwdBySms(dto);
        // 验证不通过
        if (!paramResult.getCode().equals(TransErrorCode.SUCCESS.getCode())) {
            return paramResult;
        }

        // 修改密码
        userService.updatePwdBySms(dto);
        return Result.success();
    }

    /**
     * 修改支付密码
     *
     * @param dto
     * @return
     * @throws IOException
     */
    @PutMapping(value = "/updatePayPwd")
    @PreAuthorize("@ss.login()")
    @ApiOperation("修改支付密码")
    public Result<Boolean> updatePayPwd(@RequestBody AuthcUser dto) throws IOException {
        // 校验参数
        Result<Boolean> paramResult = UserParamVerify.updatePayPwd(dto);
        // 验证不通过
        if (!paramResult.getCode().equals(TransErrorCode.SUCCESS.getCode())) {
            return paramResult;
        }

        // 参数初始化
        dto.setId(TokenUtil.getUserId());
        dto.setPayPwd(Constant.getUserPassword(dto.getPayPwd()));
        // 修改信息
        return Result.success(userService.updatePayPwd(dto));
    }

    /**
     * 修改认证信息
     *
     * @param dto
     * @return
     * @throws Exception
     */
    @PutMapping(value = "/updateAuth")
    @PreAuthorize("@ss.login()")
    @ApiOperation("修改认证信息")
    public Result<Boolean> updateAuth(@RequestBody User dto) throws Exception {
        dto.setId(TokenUtil.getUserId());
        // 校验参数
        Result<Boolean> paramResult = UserParamVerify.updateAuth(dto);
        // 验证不通过
        if (!paramResult.getCode().equals(TransErrorCode.SUCCESS.getCode())) {
            return paramResult;
        }

        User u = new User();
        // 参数初始化
        u.setId(dto.getId());
        u.setName(dto.getName());
        u.setIdCard(dto.getIdCard());
        u.setIdCardFront(dto.getIdCardFront());
        u.setIdCardVerso(dto.getIdCardVerso());
        u.setAuthStatus(EUserAuthStatus.YES.getCode());

        Status nameAndIdCard = IdCardUtil.nameAndIdCard(u.getName(), u.getIdCard());
        if (nameAndIdCard.isFail()) {
            return Result.fail("姓名身份证不匹配！");
        }
        u.setAge(IdCardUtil.getAge(u.getIdCard()));
        u.setSex(IdCardUtil.getSex(u.getIdCard()).getCode());
        // 修改信息
        userService.updateById(u);
        return Result.success();
    }

    /**
     * 获取当前佣金信息
     *
     * @return
     * @throws IOException
     */
    @GetMapping(value = "/findAppBalance")
    @PreAuthorize("@ss.login()")
    @ApiOperation(value = "获取当前佣金信息", response = UserVo.class)
    public Result<UserVo> findAppBalance() throws IOException {
        return Result.success(userService.findBalance(TokenUtil.getUserId()));
    }

    /**
     * 获取当前余额信息
     *
     * @return
     * @throws IOException
     */
    @GetMapping(value = "/findAppBrokerage")
    @PreAuthorize("@ss.login()")
    @ApiOperation(value = "获取当前余额信息", response = UserVo.class)
    public Result<UserVo> findAppBrokerage() throws IOException {
        return Result.success(userService.findBrokerage(TokenUtil.getUserId()));
    }

    /**
     * 获取下级用户列表
     *
     * @param dto
     * @return
     * @throws IOException
     */
    @GetMapping("/findXcxUnderlingByDto")
    @PreAuthorize("@ss.login()")
    @ApiOperation(value = "获取下级用户列表", response = UserVo.class)
    public Result<List<UserVo>> findXcxUnderlingByDto(UserPageDto dto) throws IOException {
        dto.setTopId(TokenUtil.getUserId());
        List<UserVo> findByDto = userService.findUnderlingByDto(dto);
        return Result.success(findByDto, findByDto);
    }

    /**
     * 获取简历
     *
     * @return
     * @throws IOException
     */
    @GetMapping("/findAppResume")
    @PreAuthorize("@ss.login()")
    @ApiOperation(value = "获取简历", response = UserVo.class)
    public Result<UserVo> findAppResume() throws IOException {
        UserVo findAppResume = userService.findResume(TokenUtil.getUserId());
        return Result.success(findAppResume);
    }

    /**
     * 将佣金转入余额
     *
     * @param total
     * @return
     * @throws IOException
     */
    @PutMapping(value = "/balanceToBrokerage/{total}")
    @PreAuthorize("@ss.login()")
    @ApiOperation("将佣金转入余额")
    public Result<Boolean> balanceToBrokerage(@PathVariable BigDecimal total) throws IOException {
        int intValue = total.intValue();
        if (intValue <= 0) {
            ExpUtil.throwEx("佣金必须大于0！");
        }

        return Result.success(userService.balanceToBrokerage(ArithUtil.intPennyToBigDollar(intValue)));
    }

    /**
     * 将佣金提现到微信
     *
     * @param total
     * @return
     * @throws IOException
     */
    @PutMapping(value = "/balanceToWx/{total}")
    @PreAuthorize("@ss.login()")
    @ApiOperation("将佣金提现到微信")
    public Result<Boolean> balanceToWx(@PathVariable BigDecimal total) throws IOException {
        int intValue = total.intValue();
        if (intValue <= 0) {
            ExpUtil.throwEx("佣金必须大于0！");
        }

        ExpUtil.throwEx("商户号必须入驻满90天且连续交易30天才可开通转账权限！");
        // return Result.success();
        return null;
    }

    /**
     * 将余额提现到微信
     *
     * @param total
     * @return
     * @throws IOException
     */
    @PutMapping(value = "/brokerageToWx/{total}")
    @PreAuthorize("@ss.login()")
    @ApiOperation("将余额提现到微信")
    public Result<Boolean> brokerageToWx(@PathVariable BigDecimal total) throws IOException {
        int intValue = total.intValue();
        if (intValue <= 0) {
            ExpUtil.throwEx("余额必须大于0！");
        }
        ExpUtil.throwEx("商户号必须入驻满90天且连续交易30天才可开通转账权限！");
        // return Result.success();
        return null;
    }

    /**
     * 生成小程序码
     *
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/addXcxCodeImg")
    @PreAuthorize("@ss.login()")
    @ApiOperation("生成小程序码")
    public Result<String> addXcxCodeImg() throws Exception {
        byte[] wxAcodeunLimit = WxUtil.getWxAcodeunLimit(((UserVo)TokenUtil.getUser()).getInvitationCode());
        UploadBean upload = FileUtil.upload(wxAcodeunLimit, "/xcxImg", "." + Constant.GENERATE_IMG_SUFFIX);
        return Result.success(upload.getObjectName());
    }

    /**
     * 用户首页统计
     *
     * @return
     * @throws Exception
     */
    @GetMapping("/countApp")
    @PreAuthorize("@ss.login()")
    @ApiOperation(value = "用户首页统计", response = Map.class)
    public Result<Map<String, Integer>> countApp() throws Exception {
        String userId = TokenUtil.getUserId();
        String userNo = TokenUtil.getUserId();
        PostApplyVo postApply = new PostApplyVo();
        postApply.setUserId(userId);
        OrderVo order = new OrderVo();
        order.setUserNo(userNo);
        HotelOrderVo hotelOrder = new HotelOrderVo();
        hotelOrder.setNoUser(userNo);
        UserCouponVo userCoupon = new UserCouponVo();
        userCoupon.setUserNo(userNo);
        userCoupon.setStatus(EUserCouponStatus.USE_NO.getCode());

        // hireIng 待录用
        // hireNo 未录用
        // postsIng 待上岗
        // payIng 待结薪
        // paymentNo 待付款
        // sendOutNo 待发货
        // sendOutYes 待收货
        // commentNo 待评价
        // paymentNoHotel 待付款
        // checkNoHotel 待入住
        // checkYesHotel 已入住
        // commentNoHotel 待评价
        // useNo 优惠券数量
        Map<String, Integer> count = new HashMap<>(5);
        count.putAll(postApplyService.countUser(postApply));
        count.putAll(orderService.countUser(order));
        count.putAll(hotelOrderService.countUser(hotelOrder));
        count.putAll(userCouponService.countUser(userCoupon));

        return Result.success(count);
    }

    @InitBinder
    @Override
    protected void initUserService() {
        setUserService((BaseUserService)userService);
    }

}